package com.anxin.registerManagement.util;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import java.io.IOException;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 叶前呈
 * @date 2022/1/25 14:11
 */
public class RSAUtil {
    //===============以下是自己封装好的一些方法，可以直接调用==================

    public static final String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCKWVwMtt6lqUjIQw3XiFGottmQ\n" +
            "IjX1YSF44GJY+KRgnqglh8wAG38urdvL/avctXmQLtEh7WUi5dTOp8zabqpVaggwatIpu8FC1yX2\n" +
            "uBlnlz5am+xRruSByiBzEjIsCpmcTJSyZYrPeVakbb+v7zYYmIOFd1OGROvU5jdEC+PcKccerZzD\n" +
            "vU/s0CFlrEqwHd3hDOFVnsrj6gkSGp9ubcJdKDQJ+EZyCEqaKA1HNBGH3ob++1R2A4A5Gm3X8C0I\n" +
            "ToPTq828QFg2Q0jnXoFETfaEB87eJyETaFc2ge3YfxGYjmJm2nvsu3rJXfwNx4nD8xL68q2Ker9e\n" +
            "w7sQk80+Q0XNAgMBAAECggEAPBzvviaHP3v6v+lCzm/Q63nntpTm1SPLI3Z7xSTkZ4cIkKYcob9Q\n" +
            "17t7UXt7fX7svxVYkWFRHIS4nsKSZCbJpCtaO49umeuW4bASMs1zXGt/EGfHmwZfC3YD+3vgiPpi\n" +
            "HGO6CHnOgq+6Ud/N9mf+HVnHa+qZRDIWNn+Ba/Ouoi5xBQXiNYhjicDIwjNH653obus9JGP1YF3c\n" +
            "/j3YlKEo58WJUY4gjKwcvfhzkaLBlElxB+sD+4775sL2DZbUxm/0K9EeXjjWShU6uTsQ0s7iG3EZ\n" +
            "L4/J5bbUqQimcUKeQoWq0w6JzqyRbsnFHm76svDWIjGqsbzvPae6Xp4PwJipgQKBgQDJhPsK+M0v\n" +
            "nlP8tgLH2eMibWIITNLKDHBFRJs4Eh4axYsLZILjqEok917JzTcXZFEF5ux8b/1cH4xWuqldYq/g\n" +
            "lM8ZCaoKz6QPryHB9iJqRLCxRKZmj9hq95e7o4VJ0bJvPggGspSjhAm39kh1jrztH+tjyGkBsY3j\n" +
            "OxyQcpa8aQKBgQCvwGaFUd93kABYlfNIO1Uyy8XIB1AIbSYAZQIOslkZLo1vNU3PlAMtfg9obLvl\n" +
            "eG1qf7HQ4VqdvLdde7xhIVDeVH+fF20ozZ20uHR3jE/Sx75+yzoW/WN0bYsWGtvwE+weqiiJ5LBs\n" +
            "XgFFWTsIQHig4kIcYbxKeR0HyJaSyczhxQKBgGEnh5CmmuXWQ0+WwIhxd5vleFngD8/xZz898Ed8\n" +
            "FJ97lamMb74qKHTh/gT0txbD+nwJ9QGZTGDZpOM7YuPu7DQuChpcGmrT6JjXKkNE0xrAux77pe3U\n" +
            "c9Y+QBzqnRwVyRzwnxX7isW6pqTWS+DBTDxWIzocKOP0Ih/nI8JQPHPhAoGAODNhVU6qFBSzV6CT\n" +
            "zExU4UpyM5XLDPbCSSwDrWlwvnG5fo9gE3n0Ti7ahH0I1MdezciJtw7pKDm5tSYlRjYeIwqISPp3\n" +
            "yK1/udOmQrhWqkN/chJQwBtFG20QJgBuxmXIgsHM9tNvayfgZimzi9759BCGLYc/a90w4FVPeR8Y\n" +
            "6jUCgYEAiW0J1q04sJQzTcvV8qd4EBrqloN0swfGZyGxbJFFYmOIHTMa7z5gnB/N+6A5UeD4kkQg\n" +
            "Z1alla7Qq+DMAznRVOH0nwbx0GJdRrGIi/LTVqXvl8rYSzyoyCEAJmMH+sbLdNvP013JPdQ1PWrz\n" +
            "3JCMFk2Qry6ymot48/BW0ZODSdc=";


    /**
     * 生成密钥对
     */
    public static KeyPair getKeyPair() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        return keyPair;
    }

    /**
     * 获取私钥和公钥，base64编码
     */
    public static Map<String, String> getKeys() throws Exception {
        KeyPair keyPair = getKeyPair();
        String publicKeyStr = getPublicKey(keyPair);
        String privateKeyStr = getPrivateKey(keyPair);
        Map<String, String> map = new HashMap<>();
        map.put("publicKey", publicKeyStr);
        map.put("privateKey", privateKeyStr);
        return map;
    }

    /**
     * 加密，并返回base64编码的结果
     */
    public static String encrypt(String message, String publicKeyStr) throws Exception {
        //将Base64编码后的公钥转换成PublicKey对象
        PublicKey publicKey = string2PublicKey(publicKeyStr);
        //用公钥加密
        byte[] publicEncrypt = publicEncrypt(message.getBytes(), publicKey);
        //加密后的内容Base64编码
        String byte2Base64 = byte2Base64(publicEncrypt);
        return byte2Base64;
    }

    /**
     * 解密，并返回字符串
     */
    public static String decrypt(String byte2Base64, String privateKeyStr) throws Exception {
        //将Base64编码后的私钥转换成PrivateKey对象
        PrivateKey privateKey = string2PrivateKey(privateKeyStr);
        //加密后的内容Base64解码
        byte[] base642Byte = base642Byte(byte2Base64);
        //用私钥解密
        byte[] privateDecrypt = privateDecrypt(base642Byte, privateKey);
        return new String(privateDecrypt);
    }

    //===============RSA的公共工具，未经过封装==================

    /**
     * 获取公钥，base64编码
     */
    public static String getPublicKey(KeyPair keyPair) {
        PublicKey publicKey = keyPair.getPublic();
        byte[] bytes = publicKey.getEncoded();
        return byte2Base64(bytes);
    }

    /**
     * 获取私钥，base64编码
     */
    public static String getPrivateKey(KeyPair keyPair) {
        PrivateKey privateKey = keyPair.getPrivate();
        byte[] bytes = privateKey.getEncoded();
        return byte2Base64(bytes);
    }

    /**
     * 将Base64编码后的公钥转换成PublicKey对象
     */
    public static PublicKey string2PublicKey(String pubStr) throws Exception {
        byte[] keyBytes = base642Byte(pubStr);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

    /**
     * 将Base64编码后的私钥转换成PrivateKey对象
     */
    public static PrivateKey string2PrivateKey(String priStr) throws Exception {
        byte[] keyBytes = base642Byte(priStr);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }

    /**
     * 公钥加密
     */
    public static byte[] publicEncrypt(byte[] content, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] bytes = cipher.doFinal(content);
        return bytes;
    }

    /**
     * 私钥加密
     */
    public static byte[] privateDecrypt(byte[] content, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] bytes = cipher.doFinal(content);
        return bytes;
    }

    /**
     * 字节数组转Base64编码
     */
    public static String byte2Base64(byte[] bytes) {
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(bytes);
    }

    /**
     * Base64编码转字节数组
     */
    public static byte[] base642Byte(String base64Key) throws IOException {
        BASE64Decoder decoder = new BASE64Decoder();
        return decoder.decodeBuffer(base64Key);
    }

    /**
     * 一个测试的demo
     */
    public static void testDemo() throws Exception {
        KeyPair keyPair = RSAUtil.getKeyPair();
        String publicKeyStr = RSAUtil.getPublicKey(keyPair);
        String privateKeyStr = RSAUtil.getPrivateKey(keyPair);
        System.out.println("RSA公钥Base64编码:" + publicKeyStr);
        System.out.println("RSA私钥Base64编码:" + privateKeyStr);

        //=================客户端=================
        //hello, i am infi, good night!加密
        String message = "hello, i am infi, good night!";
        //将Base64编码后的公钥转换成PublicKey对象
        PublicKey publicKey = RSAUtil.string2PublicKey(publicKeyStr);
        //用公钥加密
        byte[] publicEncrypt = RSAUtil.publicEncrypt(message.getBytes(), publicKey);
        //加密后的内容Base64编码
        String byte2Base64 = RSAUtil.byte2Base64(publicEncrypt);
        System.out.println("公钥加密并Base64编码的结果：" + byte2Base64);


        //##############    网络上传输的内容有Base64编码后的公钥 和 Base64编码后的公钥加密的内容     #################
        //===================服务端================
        //将Base64编码后的私钥转换成PrivateKey对象
        PrivateKey privateKey = RSAUtil.string2PrivateKey(privateKeyStr);
        //加密后的内容Base64解码
        byte[] base642Byte = RSAUtil.base642Byte(byte2Base64);
        //用私钥解密
        byte[] privateDecrypt = RSAUtil.privateDecrypt(base642Byte, privateKey);
        //解密后的明文
        System.out.println("解密后的明文: " + new String(privateDecrypt));
    }

    /**
     * 公钥，加密，给前端的
     */
    public static String PUBLICKEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQ6nv7JjOE5HefpiuedpoF1680o/O/X2\n" +
            "Y/m1JbBlqS7Q6/mv4+JQHXYyvH+VQNVTH0U1uDMXKQVYllxiX0Q6HmheFhtlgal5lQEkM181Q0VX\n" +
            "XVFQ9uboeYHLFj1uh22Hi+ZAWkNf7QN3f/koK/6/cdF4M2kx3QQHEiI8m70nPGdfbeGRyWHepu84\n" +
            "3zbWY9sJCdUjQqXePhGVt8x5Rhknb6XjfqZ0sVli2j7y3i0GdpWXpyAolBPCuliCeueXVDws/a1C\n" +
            "mfglnoAhLXRcV5p1fs7G0jGLypsU6WomPoECKj8Jj/FqTiyyjVCgxAxScZuLp6/t6ELbqrKXQAwZ\n" +
            "RuQW6wIDAQAB";
    /**
     * 私钥，解密，保存在服务器
     */
    public static String PRIVATEKEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCJDqe/smM4Tkd5+mK552mgXXrz\n" +
            "Sj879fZj+bUlsGWpLtDr+a/j4lAddjK8f5VA1VMfRTW4MxcpBViWXGJfRDoeaF4WG2WBqXmVASQz\n" +
            "XzVDRVddUVD25uh5gcsWPW6HbYeL5kBaQ1/tA3d/+Sgr/r9x0XgzaTHdBAcSIjybvSc8Z19t4ZHJ\n" +
            "Yd6m7zjfNtZj2wkJ1SNCpd4+EZW3zHlGGSdvpeN+pnSxWWLaPvLeLQZ2lZenICiUE8K6WIJ655dU\n" +
            "PCz9rUKZ+CWegCEtdFxXmnV+zsbSMYvKmxTpaiY+gQIqPwmP8WpOLLKNUKDEDFJxm4unr+3oQtuq\n" +
            "spdADBlG5BbrAgMBAAECggEAQ7QfnYyLgub4XAMZ/eeYwAUtlT0aG46XFi/mEiYfMgHUZp1DC/lh\n" +
            "xgv7aC5GFm7KzumrbcCfMj5X0n70gUb8xsSbpaQG8pQ7YSXdMhtX/lEkpQ5kRnMuZ8d8ARJ7pR6w\n" +
            "FKW7KFub6UMLJwZ3l7QR8jGdhRfz78/rhkOvWOeJmEZnLS0ruRJQFDJSipGgHDIHh1EALvBFXV0B\n" +
            "gZErnzOqyY85vdo0sfpWWPDt1XK2lshXTCXyx0n3XftysNIXDOaNN8HPUOuisplOBSr2zFsm1yR1\n" +
            "D5Fm4uA40Xw1wXO5rJiXPmgEp5mT9x1j7atEupYxi20wnJLCBE17+Z/WJRe0AQKBgQDBsoMmJW23\n" +
            "VmU/EpIpUUk/DWv14orTf47P4DGNcMnzoKaJvrItq/gIxQYuNAONnE4S0OOCycMReyiotRtIcOdq\n" +
            "qUs/+sfi6f1gJc0kxOKk8J3pJ0GS75DmwhMRs5ohw3xRavo+IX+YttkGE/1gdDqtQ5T3ZWJu0j3i\n" +
            "FMuctrp7AQKBgQC1JESea8cqiXBRWFZWlLIN2qAfgYkItPiq/9Vlcum/iqj5RNFabL1w5OFqOwpU\n" +
            "7LJZg+i9qVGi1vFYBd/7tU/nJRZfqBnKTW1yNBH4PSB0QX4vQggiUh6BU/JT7rMaydcrach6Uft3\n" +
            "7reJZLSbHkRCD6mRZBbrZ+dBNBQIMBYt6wKBgQCUdzixL3UmVtFqA9kGVGjZLHd407jnHdmgGk7B\n" +
            "BBe3ZobgA8vc1/hY+HOhTHsAuzLYl0YbhHzBVG44ygBsiSXICpVEJ/u4QPPWE4NnUIYMOOZAxLct\n" +
            "YfTl+xHUup5EjOsoGOBQaSq9KkG0t/O5T719+tQewJYvLXUDaj8bErBjAQKBgE8wstr7TU/4U+UM\n" +
            "FHq3ePv7hyMe8zSeQVQokjdOvIfja6nF/yxj+5HeTfmuI/8ql3Hw7A/2dN0W0N3le51ED9GCcjyR\n" +
            "dezuWpmhz/VRa93HQA4S9RFkCzgI5hjxctWURgARt/ZZ3vD4qL5lC1wBKGAlDsGkGy0A+KWVyegm\n" +
            "dZvPAoGAXVBY9wm4IhtkXWP1Wlil9pNwAsV2/hA2XlM/a9ZK1LCth4IeaaNbCdZBIerX9kT6Gyo2\n" +
            "GIKCEfKFhHszniTOPJMz8ykzXq1/ti3kGHiE8sMfJ9wUEFL5KlZbfQtdBtZkaYU2phT+JbpRBHKJ\n" +
            "cfSAq9tP9BDmykW143qJNe2+taA=\n";

}
